/**
 * @(#)AppServiceApplication.java, 2017-2-6. Copyright 2017 Meituan, Inc. All
 *                                 rights reserved. MEITUAN
 *                                 PROPRIETARY/CONFIDENTIAL. Use is subject to
 *                                 license terms.
 */
package com.empress.uranus.zma.web;

import com.google.common.collect.Sets;
import com.empress.uranus.zma.web.controller.NapkinController;

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * 整体启动的方法，可以直接用springboot方式启动本工程或者运行本类的main函数，然后浏览器上输入
 * http://localhost:8081/hello1 即可以看到<br>
 */
@Configuration
@ComponentScan(basePackages = {
    "com.empress.uranus.zma.*"
})
@Component("appServiceApplication")
public class AppServiceApplication {

    @Autowired
    private String projectName;

    @Autowired
    private String author;

    @Value("${jetty.logs}")
    private String jettyLogPath;

    @Value("${jetty.threadPool.maxThread}")
    private int jettyMaxThread;

    @Value("${jetty.threadPool.minThreads}")
    private int jettyMinThread;

    @Value("${jetty.threadPool.idleTimeout}")
    private int jettyIdleTimeout;

    @Value("${jetty.threadPool.queueSize}")
    private int jettyQueueSize;

    @Value("${jetty.request.size}")
    private int jettyRequestHeaderSize;

    @Value("${jetty.threadPool.maxThread}")
    private int jettyResponseHeaderSize;

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();

        factory.addServerCustomizers(new JettyServerCustomizer() {
            public void customize(Server server) {
                HandlerCollection handlers = new HandlerCollection();
                for (Handler handler : server.getHandlers()) {
                    handlers.addHandler(handler);
                }
                RequestLogHandler reqLogs = new RequestLogHandler();
                NCSARequestLog reqLogImpl = new NCSARequestLog(jettyLogPath + "/" + projectName + ".request-yyyy_mm_dd.log");
                reqLogImpl.setRetainDays(30);
                reqLogImpl.setAppend(true);
                reqLogImpl.setExtended(false);
                reqLogImpl.setLogTimeZone("GMT");
                reqLogs.setRequestLog(reqLogImpl);
                handlers.addHandler(reqLogs);
                server.setHandler(handlers);
            }
        });

        factory.addServerCustomizers(new JettyServerCustomizer() {
            public void customize(Server server) {
                QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class);
                threadPool.setMaxThreads(jettyMaxThread);
                threadPool.setMinThreads(jettyMinThread);
                threadPool.setIdleTimeout(jettyIdleTimeout);
            }
        });

        factory.addServerCustomizers(new JettyServerCustomizer() {

            @Override
            public void customize(Server server) {
                for (Connector connector : server.getConnectors()) {
                    if (connector instanceof ServerConnector) {
                        HttpConnectionFactory connectionFactory = ((ServerConnector) connector)
                                .getConnectionFactory(HttpConnectionFactory.class);
                        connectionFactory.getHttpConfiguration()
                                .setRequestHeaderSize(jettyRequestHeaderSize);
                        connectionFactory.getHttpConfiguration().setResponseHeaderSize(jettyResponseHeaderSize);

                    }
                }
            }
        });
        return factory;
    }

    public static void main(String[] args) {

        SpringApplication application = new SpringApplication(
                NapkinController.class);
        // 这里可以补充那些加载application.xml之类的操作, 我这里给个例子，我在例子里面直接通过xml去import xml了
        Set<Object> sourcesSet = Sets.newHashSet();
        sourcesSet.add("classpath:applicationContext.xml");
        application.setSources(sourcesSet);
        application.run(args);

    }
}
